<!DOCTYPE HTML>
<html>
<head>
<title>Input | AutoHotkey</title>
<meta name="description" content="The Input command waits for the user to type a string." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
</head>
<body>

<h1>Input</h1>

<p>等待用户输入字符串.</p>

<pre class="Syntax"><span class="func">Input</span> <span class="optional">, OutputVar, Options, EndKeys, MatchList</span></pre>
<h2>参数</h2>
<dl>

  <dt>OutputVar</dt>
  <dd><p>用来保存用户输入文本的变量名(默认情况下, 模拟输入也被保存下来).</p>
      <p>如果省略此参数和其他参数, 那么会终止在其他<a href="../misc/Threads.htm">线程</a>中正在执行的任何 Input 并且将那个 Input 的 <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 设置为单词 NewInput. 与之相比, 如果终止了之前的 Input 则把当前线程的 <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 设置为 0, 如果没有需要终止的 Input 则为 1.</p>
      <p><em>OutputVar</em> 本身并不记录键击. 而是记录通过键击根据活动窗口的键盘布局/语言产生的字符. 因此, 不产生字符的键击(例如 <kbd>PageUp</kbd> 和 <kbd>Home</kbd>) 不会被记录下来(尽管可以通过下面的 <em>EndKeys</em> 参数识别它们).</p>
      <p class="warning"><strong>注意:</strong> <kbd>Escape</kbd> 键被转换为 ASCII ESC 字符, <code>Chr(27)</code>. 这可以通过在 <em>EndKeys</em> 中包含 <code>{Esc}</code> 来避免, 在这种情况下, 按下 <kbd>Escape</kbd> 将终止输入.</p>
      <p>会原义保存空白字符, 例如 <kbd>Tab</kbd>(`t). <kbd>Enter</kbd> 被保存为换行符(`n).</p></dd>

  <dt>选项</dt>
  <dd><p><u>由零个或多个下列字母组成的字符串(可任意顺序, 字母间可以用空格分隔):</u></p>
      <p><strong>B</strong>: 忽略 <kbd>Backspace</kbd>(退格)键. 一般情况下, 按下 <kbd>Backspace</kbd> 键会删除最后一个输入的字符. 注: 如果输入的文本是可见的(例如在编辑器中), 在其中使用方向键或其他方式移动了光标后, <kbd>Backspace</kbd> 键仍然会删除最后一个字符而不是光标(插入点) 后面的字符.</p>
      <p><strong>C</strong>: 区分大小写. 一般情况下, <em>MatchList</em> 是不区分大小写的(在 1.0.43.03 之前的版本中, 只有字母 A-Z 被认为具有大小写形式, 而像 ü/ü 这样的字母则没有).</p>
      <p><strong>I</strong>: 忽略由 AutoHotkey 脚本产生的所有字符, 例如 <a href="Send.htm#SendEvent">SendEvent</a> 命令. 然而, 不论此设置如何, <a href="Send.htm#SendInput">SendInput</a> 和 <a href="Send.htm#SendPlay">SendPlay</a> 模式生成的输入总是被忽略.</p>      
      <p><strong>L</strong>: 长度限制(例如 <code>L5</code>). 允许输入文本的最大长度. 当文本到达这个长度, 则输入会被终止且 <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 被设置为单词 Max, 不过如果此时文本匹配 <em>MatchList</em> 中的某个词组, 则把 <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 设置为单词 Match. 如果未指定, 则长度限制为 16383, 这也是绝对的最大长度.</p>
      <p><strong>M</strong>: 如果含修饰符的键击(例如 <kbd>Control</kbd>+<kbd>A</kbd> 到 <kbd>Control</kbd>+<kbd>Z</kbd>) 对应于真实的 ASCII 字符, 则会识别并对它们进行转译. 参考这个例子, 其中识别了 <kbd>Control</kbd>+<kbd>C</kbd>: </p>
      <pre>Transform, CtrlC, Chr, 3 <em>; 把 Ctrl-C 对应的字符保存到 CtrlC 变量.</em>
Input, OutputVar, L1 M
if OutputVar = %CtrlC%
    MsgBox, You pressed Control-C.
ExitApp</pre>
      <p class="note"><strong>注意</strong>: 从 <kbd>Ctrl</kbd>+<kbd>A</kbd> 到 <kbd>Ctrl</kbd>+<kbd>Z</kbd> 对应的字符为从 <a href="Chr.htm">Chr(1)</a> 到 <a href="Chr.htm">Chr(26)</a>. 此外, <strong>M</strong> 选项可能会导致某些键盘快捷键(例如 <kbd>Ctrl</kbd>+<kbd>&larr;</kbd>) 在 Input 执行时表现不正常.</p>
      <p><strong>T</strong>: 超时(例如 <code>T3</code>). 在终止输入前等待的秒数, 超时后设置 <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 为单词 Timeout.Input 超时后, <em>OutputVar</em> 会被设置为用户在超时前输入的文本. 这个值可以为浮点数, 例如 <code>2.5</code>.</p>      
      <p id="vis"><strong>V</strong>: 可见. 一般情况下, 用户的输入是阻塞的(隐藏在操作系统后). 使用此选项来发送用户的键击到活动窗口.</p>
      <p id="asterisk"><strong>*</strong>: 通配符(查找所有地方). 一般情况下, 用户输入的文本必须准确匹配 <em>MatchList</em> 中的某个词组, 匹配才会成功. 使用此选项搜索输入文本的整个长度, 这样会更容易找到匹配.</p>
      <p id="E"><strong>E</strong> <span class="ver">[v1.1.20+]</span>: 使结束键响应单个字符而替代使用 keycode(按键码). 这样使得当用户键盘布局和脚本的不同的时候得到一致的返回值. 同时它还能避免实际发生的组合键和定义的不同的歧义; 举个例子, 如果 <code>@</code> 作为 结束键, 在 US 键盘布局上 <kbd>Shift</kbd>+<kbd>2</kbd> 会触发它, 但是 <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>2</kbd> 不会(如果使用了 E 选项的话). 如果 <strong>C</strong> 选项也同时开启, 那么结束字符是大小写敏感的.</p>
      </dd>

  <dt>EndKeys</dt>
  <dd><p>零个或多个按键组成的列表, 按下其中的任何一个都可以终止输入(<em>EndKey</em> 自身不会被写入 <em>OutputVar</em>). 使用此方式终止输入后, <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 被设置为单词 EndKey 后跟着冒号和 <em>EndKey</em> 的名称. 例如: <code>EndKey:.</code>, <code>EndKey:Escape</code>.</p>
      <p><em>EndKey</em> 列表使用类似于 <a href="Send.htm">Send</a> 命令的格式. 例如, 指定 <code>{Enter}.{Esc}</code> 会使得 <kbd>Enter</kbd>, <kbd>.</kbd> 或 <kbd>Escape</kbd> 其中任何一个都可以终止输入. 要使用大括号作为终止键, 请指定 <code>{{}</code> 和/或 <code>{}}</code>.</p>
      <p>要使用 <kbd>Control</kbd>, <kbd>Alt</kbd> 或 <kbd>Shift</kbd> 作为终止键, 请指定它们的左和/或右版本, 而不是中性版本. 例如, 指定 <code>{LControl}{RControl}</code> 而不是 <code>{Control}</code>.</p>
      <p><span class="ver">[v1.0.14+]</span>: 尽管不支持诸如 <kbd>Alt</kbd>+<kbd>C</kbd>(!c) 这样的修饰键, 但支持某些需要按住 <kbd>shift</kbd> 键来输入的字符,标点符号, 例如 <code>?!:@&amp;{}</code>. <span class="ver">[v1.1.20+]</span>: 其他字符推荐使用上述的 <strong>E</strong> 选项. 当同时使用 <strong>E</strong> 和 <strong>M</strong> 选项时, 通过在 <em>EndKeys</em> 中包括相应的 ASCII 控制字符来支持 <kbd>Control</kbd>+<kbd>A</kbd> 到 <kbd>Control</kbd>+<kbd>Z</kbd>.</p>
      <p>还可以指定明确的虚拟按键代码, 例如 <code>{vkFF}</code>. 只有在一个按键没有指定名称且按下时不产生可见的字符这样少见的情况下, 这种方法才有用. 它的虚拟按键代码可以通过<a href="../KeyList.htm#SpecialKeys">按键列表页面</a>底部的步骤来确定.</p>
    </dd>

  <dt>MatchList</dt>
  <dd><p>逗号分隔的关键词组列表, 其中的任何一个都可以终止输入(此时 <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 被设置为单词 Match). 用户输入的全部文本必须准确匹配列表中的某个词组, 匹配才会成功(除非使用了 <a href="#asterisk">* 选项</a>). 此外, <strong>在分隔逗号周围的任何空格或 tab 都是有意义的</strong>, 这表示它们也是匹配字符串的一部分. 例如, 如果 <em>MatchList</em> 为 <code>ABC , XYZ</code>, 则用户必须输入在 ABC 后或 XYZ 前输入空格才形成匹配.</p>
      <p>在匹配列表中两个连续的逗号产生单个原义逗号. 例如, 后面的匹配列表会在 string1 的末尾产生单个原义逗号: <code>string1,,,string2 </code>. 同样地, 后面的匹配列表仅包含其中含有一个原义逗号的单个项目: <code>single,,item</code>.</p>
    <p>因为 <em>MatchList</em> 中的每一项并不是作为独立的参数, 所以此列表可以完整的包含在一个变量中. 事实上, 如果此列表的长度超过 16383, 那么列表的全部或部分必须包含在变量中以变量表示, 因为这个长度是任何脚本行的最大长度. 例如, <em>MatchList</em> 可以由 <code>%List1%,%List2%,%List3%</code> 组成, 其中的每个变量包含了用来匹配词组的一个大的子列表.</p>
    </dd>

</dl>

<h2>ErrorLevel</h2>
<p><span class="ver">[v1.1.04+]</span> 此命令在不带参数调用且没有 Input 正在执行时会抛出异常. 想了解更多信息, 请参阅<a href="Catch.htm#RuntimeErrors">运行时错误</a>.</p>
<table class="info">
  <tr>
    <td style="width:15%"><p>1 或 0</p></td>
    <td><p>不带参数使用此命令时, 如果成功终止了之前的 Input 则 <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 被设置为 0, 或是如果没有需要终止的 Input 则为 1.</p></td>
  </tr>
  <tr>
    <td>NewInput</td>
    <td>此 Input 被另一个使用 Input 的<a href="../misc/Threads.htm">线程</a>中断.</td>
  </tr>
  <tr>
    <td>Max</td>
    <td>输入的文本达到了允许的最大长度且没有匹配 <em>MatchList</em> 中的任何一项.</td>
  </tr>
  <tr>
    <td>Timeout</td>
    <td>输入超时时间.</td>
  </tr>
  <tr>
    <td>Match</td>
    <td>输入的内容匹配 <em>MatchList</em> 中的某项.</td>
  </tr>
  <tr>
    <td>EndKey:<em>Name</em></td>
    <td>
      <p><em>EndKeys</em> 的某个终止键被按下用于终止输入. 此时, <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 包含单词 EndKey 后跟着冒号和不带大括号的终止键的名称, 例如 <code>EndKey:Enter</code>, <code>EndKey:Escape</code> 等等.</p>
      <p>注意 <em>Name</em> 是按键的 "标准" 名称而不管写到 <em>EndKeys</em> 中的方式. 举个例子, <code>{Esc}</code> 和 <code>{vk1B}</code> 都返回 <code>EndKey:Escape</code>. <a href="GetKey.htm">GetKeyName()</a> 可用于获取标准名称.</p>
      <p>如果使用了 <a href="#E">E 参数</a>, <em>Name</em> 则为实际输入的字符(如果适用的话). 其他情况下, 按键名取决于当前实际使用的键盘布局.</p>
      <p>在 <span class="ver">[v1.1.20]</span> 之前, 如果 EndKey 的 VK 码在 0x41(A) 到 0x5A(Z) 的范围内时, ErrorLevel 通常包含类似 ASCII 的字符, 甚至不符合当前键盘布局. 而从 <span class="ver">[v1.1.20]</span> 开始, 则一定是符合当前键盘布局的. 如果使用从 A 到 Z 的字符, 那么当它是大写字母时可保持向后兼容; 否则可以是小写字母.</p>
    </td>
  </tr>
</table>
<h2>备注</h2>
<p>如果在使用此命令时另一个<a href="../misc/Threads.htm">线程</a>中的 Input 正在执行, 则那个 Input 会被终止且其 <a href="../misc/ErrorLevel.htm">ErrorLevel</a> 会被设置为单词 NewInput. 之后(如果给出了参数), 新的 Input 开始执行.</p>
<p>在执行 Input 时, 仍然可以启动新的<a href="../misc/Threads.htm">线程</a>(例如, <a href="Menu.htm">自定义菜单项</a>和<a href="SetTimer.htm">计时子程序</a>). 同样地, 当 Input <a href="#vis">可见</a> 时键盘<a href="../Hotkeys.htm">热键</a>仍然是有效的. 如果 Input 不可见, 那么只会触发<a href="_UseHook.htm">钩子热键</a>.</p>
<p>脚本中首次使用此命令时, 会安装<a href="_InstallKeybdHook.htm">键盘钩子</a>(在还没有安装时). 同时, 脚本变成<a href="_Persistent.htm">持续运行的</a>, 这意味着应该使用 <a href="ExitApp.htm">ExitApp</a> 结束脚本. 键盘钩子会一直保持加载状态, 直到下一次使用 <a href="Suspend.htm">Suspend</a> 或 <a href="Hotkey.htm">Hotkey</a> 命令, 此时如果没有任何热键或热字串需要那么它会被移除.</p>
<p>如果您使用多种语言或多种键盘布局, 则 Input 会使用活动窗口的键盘布局而不是脚本的(不论 Input 是否<a href="#vis">可见</a>). 然而, 在 1.0.44.03 之前的脚本中, 则使用脚本自己的布局.</p>
<p>尽管不够灵活, 但<a href="Hotstrings.htm">热字串</a>通常比 Input 命令更容易使用.</p>
<h2>相关</h2>
<p><a href="KeyWait.htm">KeyWait</a>, <a href="Hotstrings.htm">热字串</a>, <a href="InputBox.htm">InputBox</a>, <a href="_InstallKeybdHook.htm">#InstallKeybdHook</a>, <a href="../misc/Threads.htm">线程</a>, <a href="IfIn.htm">if var in/contains MatchList</a></p>
<h2>示例</h2>
<pre class="NoIndent"><em>; 等待用户按下任意键.  产生不可见字符的这些键(例如
; 修饰键, 功能键和方向键) 已经被列为终止键, 这样
; 就能检测到它们.</em>
Input, SingleKey, L1, {LControl}{RControl}{LAlt}{RAlt}{LShift}{RShift}{LWin}{RWin}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{BS}{CapsLock}{NumLock}{PrintScreen}{Pause}</pre>
<pre class="NoIndent"><em>; 这是个可运行的热键示例.  由于此热键含有颚化符(~)
; 前缀, 所以它本身的键击会被传递到活动窗口.
; 因此, 如果您键入 [btw(或其他某个匹配
; 词组) 到任意编辑器中, 脚本会自动执行
; 您选择的动作(例如替换键入的文本):</em>

~[::
Input, UserInput, V T5 L4 C, {enter}.{esc}{tab}, btw,otoh,fl,ahk,ca
if (ErrorLevel = "Max")
{
    MsgBox, You entered &quot;%UserInput%&quot;, which is the maximum length of text.
    return
}
if (ErrorLevel = "Timeout")
{
    MsgBox, You entered &quot;%UserInput%&quot; at which time the input timed out.
    return
}
if (ErrorLevel = "NewInput")
    return
If InStr(ErrorLevel, "EndKey:")
{
    MsgBox, You entered &quot;%UserInput%&quot; and terminated the input with %ErrorLevel%.
    return
}
<em>; 否则, 找到了匹配.</em>
if (UserInput = "btw")
    Send, {backspace 4}by the way
else if (UserInput = "otoh")
    Send, {backspace 5}on the other hand
else if (UserInput = "fl")
    Send, {backspace 3}Florida
else if (UserInput = "ca")
    Send, {backspace 3}California
else if (UserInput = "ahk")
    Run, https://autohotkey.com
return</pre>

</body>
</html>